########################################################################
#
# Ots Hardware Mapping Language (OHML) Source File
#
# Hardware : Denon DN-HC4500 DJ MIDI Hardware Controller
# File Name : (Ots) Denon DN-HC4500.ohm
# Last Updated : 31-Jul-2012
# OtsAV Version : 1.90.000
#
# Copyright 1996-2012 Ots Corporation
#
# IMPORTANT NOTE: This is an original file from Ots Labs. If you wish to
# make edits, it is recommended that you copy the contents of this file
# to a new file first. Should you fail to do this, your changes may be
# lost when Ots software updates are installed on your computer. If you
# need to obtain the original version of this file at a later stage,
# visit http://www.OtsAV.com
#
########################################################################
# ******* Declare variables *******
# Arguments: variable name, initial value, maximum value
!var[$init_counter,10,10] # delayed init counter
!var[$abm_active,0,1] # tracks abm active state
!var[$video_master,0,1] # tracks video master deck
!var[$playlist_nav,0,1] # tracks playlist navigation state
!var[$playlist_nav_last_deck,0,1] # 0 = deck A, 1 = deck B
!var[$playlist_nav_activity,0,1] # 1 = some nav activity has occurred
!var[$global_shift,0,1] # global shift state
!var[$deck_a_shift,0,1] # tracks shift button
!var[$deck_b_shift,0,1]
!var[$deck_a_time_mode,0,1] # 0 = elapsed, 1 = remaining
!var[$deck_b_time_mode,0,1]
!var[$deck_a_loaded,0,1] # 0 = empty, 1 = loaded
!var[$deck_b_loaded,0,1]
!var[$deck_a_playing,0,1] # 1 = playing
!var[$deck_b_playing,0,1]
!var[$deck_a_jog_mode,0,1] # 0 = bending, 1 = scratching
!var[$deck_b_jog_mode,0,1]
!var[$deck_a_jog_button,0,1] # 1 = down (pressed)
!var[$deck_b_jog_button,0,1]
!var[$deck_a_touch_dot,0,1] # for switching touch dot led
!var[$deck_b_touch_dot,0,1]
!var[$deck_a_bend_state,0,1] # tracks jog wheel state for bending
!var[$deck_b_bend_state,0,1]
!var[$deck_a_scratch_state,0,2] # tracks jog wheel state for scratching
!var[$deck_b_scratch_state,0,2]
!var[$deck_a_scratch,0,1] # 1 = currently scratching
!var[$deck_b_scratch,0,1]
!var[$deck_a_bend,0,1] # 1 = currently bending
!var[$deck_b_bend,0,1]
!var[$deck_a_bend_down,0,1] # 1 = currently bend down
!var[$deck_b_bend_down,0,1]
!var[$deck_a_bend_up,0,1] # 1 = currently bend up
!var[$deck_b_bend_up,0,1]
!var[$deck_a_frame_search,0,1] # 1 = in frame search mode
!var[$deck_b_frame_search,0,1]
!var[$deck_a_search_spin_counter,0,81] # for dividing (by 80) jog
!var[$deck_b_search_spin_counter,0,81] # pulses when frame searching
!var[$deck_a_search_rate,0,2] # frame search speed via jog
!var[$deck_b_search_rate,0,2]
!var[$deck_a_zorphing,0,1] # for tracking scratching/zorphing mode
!var[$deck_b_zorphing,0,1]
!var[$deck_a_bend_tempo,0,1] # for tracking bending mode
!var[$deck_b_bend_tempo,0,1]
!var[$deck_a_slider_index,0,2] # 0 = tempo, 1 = pitch, 2 = direction
!var[$deck_b_slider_index,0,2]
!var[$deck_a_slider_button_count,0,8] # for tracking time button held
!var[$deck_b_slider_button_count,0,8]
!var[$deck_a_playlist_button_count,0,21] # for tracking time button held
!var[$deck_b_playlist_button_count,0,21]
!var[$deck_a_video_block,0,1] # tracks video block state
!var[$deck_b_video_block,0,1]
!var[$deck_a_flip,0,1] # tracks flip button
!var[$deck_b_flip,0,1]
!var[$deck_a_a1,0,1] # tracks a1 button
!var[$deck_b_a1,0,1]
!var[$deck_a_a2,0,1] # tracks a2 button
!var[$deck_b_a2,0,1]
!var[$deck_a_exit,0,1] # tracks exit-reloop button
!var[$deck_b_exit,0,1]
!var[$deck_a_mod,0,3] # tracks flip/exit modifiers
!var[$deck_b_mod,0,3]
# ******* Declare subroutines *******
!sub[@deck_a_try_bend] # this sub is used purely to gain
!sub[@deck_b_try_bend] # use of another conditional
!sub[@deck_a_try_scratch]
!sub[@deck_b_try_scratch]
!sub[@deck_a_try_scratch2]
!sub[@deck_b_try_scratch2]
!sub[@deck_a_jog_val_bend] # important to use sub for midi.velval-based
!sub[@deck_b_jog_val_bend] # controls which call more than one command
# in order to be efficient (CPU resources)
!sub[@deck_a_jog_val_scratch]
!sub[@deck_b_jog_val_scratch]
!sub[@deck_a_cue_no_shift]
!sub[@deck_b_cue_no_shift]
!sub[@deck_a_slider_val] # new value from slider
!sub[@deck_b_slider_val]
!sub[@deck_a_slider_val_tempo]
!sub[@deck_b_slider_val_tempo]
!sub[@deck_a_slider_val_pitch]
!sub[@deck_b_slider_val_pitch]
!sub[@deck_a_slider_val_direction]
!sub[@deck_b_slider_val_direction]
!sub[@deck_a_slider_info] # display slider assignment info
!sub[@deck_b_slider_info]
!sub[@deck_a_playlist_button_up] # playlist button released
!sub[@deck_b_playlist_button_up] # prior to eject being invoked
!sub[@deck_a_playlist_nav] # invoke playlist navigation
!sub[@deck_b_playlist_nav]
!sub[@deck_a_playlist_loadnext] # load next item from playlist if
!sub[@deck_b_playlist_loadnext] # deck is not currently playing
# ******* Declare LEDs/blink assets *******
# Arguments: blink handle name, "M", midi off code, midi on code
!blink[~deck_a_cue_led,M,0xB0:0x4B:0x26,0xB0:0x4A:0x26]
!blink[~deck_b_cue_led,M,0xB1:0x4B:0x26,0xB1:0x4A:0x26]
!blink[~deck_a_playpause_led,M,0xB0:0x4B:0x27,0xB0:0x4A:0x27]
!blink[~deck_b_playpause_led,M,0xB1:0x4B:0x27,0xB1:0x4A:0x27]
!blink[~deck_a_jog_mode_led,M,0xB0:0x4B:0x06,0xB0:0x4A:0x06]
!blink[~deck_b_jog_mode_led,M,0xB1:0x4B:0x06,0xB1:0x4A:0x06]
!blink[~deck_a_jog_led,M,0xB0:0x4B:0x3B,0xB0:0x4A:0x3B]
!blink[~deck_b_jog_led,M,0xB1:0x4B:0x3B,0xB1:0x4A:0x3B]
!blink[~deck_a_touch_dot,M,0xB0:0x4E:0x20,0xB0:0x4D:0x20]
!blink[~deck_b_touch_dot,M,0xB1:0x4E:0x20,0xB1:0x4D:0x20]
!blink[~deck_a_slider_led_green,M,0xB0:0x4B:0x07,0xB0:0x4A:0x07]
!blink[~deck_b_slider_led_green,M,0xB1:0x4B:0x07,0xB1:0x4A:0x07]
!blink[~deck_a_slider_led_orange,M,0xB0:0x4B:0x08,0xB0:0x4A:0x08]
!blink[~deck_b_slider_led_orange,M,0xB1:0x4B:0x08,0xB1:0x4A:0x08]
!blink[~deck_a_fx_1_led,M,0xB0:0x4B:0x0B,0xB0:0x4A:0x0B]
!blink[~deck_b_fx_1_led,M,0xB1:0x4B:0x0B,0xB1:0x4A:0x0B]
!blink[~deck_a_fx_2_led,M,0xB0:0x4B:0x0D,0xB0:0x4A:0x0D]
!blink[~deck_b_fx_2_led,M,0xB1:0x4B:0x0D,0xB1:0x4A:0x0D]
!blink[~deck_a_fx_3_led,M,0xB0:0x4B:0x0F,0xB0:0x4A:0x0F]
!blink[~deck_b_fx_3_led,M,0xB1:0x4B:0x0F,0xB1:0x4A:0x0F]
!blink[~deck_a_func_1_led,M,0xB0:0x4B:0x11,0xB0:0x4A:0x11]
!blink[~deck_b_func_1_led,M,0xB1:0x4B:0x11,0xB1:0x4A:0x11]
!blink[~deck_a_func_2_led,M,0xB0:0x4B:0x13,0xB0:0x4A:0x13]
!blink[~deck_b_func_2_led,M,0xB1:0x4B:0x13,0xB1:0x4A:0x13]
!blink[~deck_a_func_3_led,M,0xB0:0x4B:0x15,0xB0:0x4A:0x15]
!blink[~deck_b_func_3_led,M,0xB1:0x4B:0x15,0xB1:0x4A:0x15]
!blink[~deck_a_func_4_led,M,0xB0:0x4B:0x17,0xB0:0x4A:0x17]
!blink[~deck_b_func_4_led,M,0xB1:0x4B:0x17,0xB1:0x4A:0x17]
!blink[~deck_a_func_5_led,M,0xB0:0x4B:0x19,0xB0:0x4A:0x19]
!blink[~deck_b_func_5_led,M,0xB1:0x4B:0x19,0xB1:0x4A:0x19]
!blink[~deck_a_playlist_led,M,0xB0:0x4B:0x02,0xB0:0x4A:0x02]
!blink[~deck_b_playlist_led,M,0xB1:0x4B:0x02,0xB1:0x4A:0x02]
!blink[~deck_a_parameter_led,M,0xB0:0x4B:0x1E,0xB0:0x4A:0x1E]
!blink[~deck_b_parameter_led,M,0xB1:0x4B:0x1E,0xB1:0x4A:0x1E]
# ******* Initialisation *******
# Called by OHM subsystem at startup.
# Place any code here that is important to maintain state at launch
sub[@_init] {
# turn off all LEDs we don't explicitly handle
midiOut(0xB0:0x4B:0x04) # pitch match
midiOut(0xB1:0x4B:0x04)
midiOut(0xB0:0x4B:0x05) # jog mode green
midiOut(0xB1:0x4B:0x05)
midiOut(0xB0:0x4B:0x09) # tap green
midiOut(0xB1:0x4B:0x09)
midiOut(0xB0:0x4B:0x0A) # tap orange
midiOut(0xB1:0x4B:0x0A)
midiOut(0xB0:0x4B:0x0C) # fx 1 green
midiOut(0xB1:0x4B:0x0C)
midiOut(0xB0:0x4B:0x0E) # fx 2 green
midiOut(0xB1:0x4B:0x0E)
midiOut(0xB0:0x4B:0x10) # fx 3 green
midiOut(0xB1:0x4B:0x10)
midiOut(0xB0:0x4B:0x12) # hot 1 dimmer
midiOut(0xB1:0x4B:0x12)
midiOut(0xB0:0x4B:0x14) # hot 2 dimmer
midiOut(0xB1:0x4B:0x14)
midiOut(0xB0:0x4B:0x16) # hot 3 dimmer
midiOut(0xB1:0x4B:0x16)
midiOut(0xB0:0x4B:0x18) # hot 4 dimmer
midiOut(0xB1:0x4B:0x18)
midiOut(0xB0:0x4B:0x1A) # hot 5 dimmer
midiOut(0xB1:0x4B:0x1A)
midiOut(0xB0:0x4B:0x24) # a1
midiOut(0xB1:0x4B:0x24)
midiOut(0xB0:0x4B:0x3C) # a1 dimmer
midiOut(0xB1:0x4B:0x3C)
midiOut(0xB0:0x4B:0x25) # a2
midiOut(0xB1:0x4B:0x25)
midiOut(0xB0:0x4B:0x3D) # a2 dimmer
midiOut(0xB1:0x4B:0x3D)
# turn off all screen segments that aren't explicitly handled
midiOut(0xB0:0x4E:0x01) # T.
midiOut(0xB1:0x4E:0x01)
midiOut(0xB0:0x4E:0x04) # CONT.
midiOut(0xB1:0x4E:0x04)
midiOut(0xB0:0x4E:0x05) # SINGLE
midiOut(0xB1:0x4E:0x05)
midiOut(0xB0:0x4E:0x06) # BPM
midiOut(0xB1:0x4E:0x06)
midiOut(0xB0:0x4E:0x10) # MP3
midiOut(0xB1:0x4E:0x10)
midiOut(0xB0:0x4E:0x11) # WAV
midiOut(0xB1:0x4E:0x11)
midiOut(0xB0:0x4E:0x13) # KB
midiOut(0xB1:0x4E:0x13)
midiOut(0xB0:0x4E:0x14) # KEY ADJ.
midiOut(0xB1:0x4E:0x14)
midiOut(0xB0:0x4E:0x15) # MEMO
midiOut(0xB1:0x4E:0x15)
midiOut(0xB0:0x4E:0x16) # ( : A1 side
midiOut(0xB1:0x4E:0x16)
midiOut(0xB0:0x4E:0x17) # ( : A2 side
midiOut(0xB1:0x4E:0x17)
midiOut(0xB0:0x4E:0x18) # ) : A1 side
midiOut(0xB1:0x4E:0x18)
midiOut(0xB0:0x4E:0x19) # ) : A2 side
midiOut(0xB1:0x4E:0x19)
midiOut(0xB0:0x4E:0x1A) # A1
midiOut(0xB1:0x4E:0x1A)
midiOut(0xB0:0x4E:0x1B) # A2
midiOut(0xB1:0x4E:0x1B)
midiOut(0xB0:0x4E:0x1C) # B : A1 side
midiOut(0xB1:0x4E:0x1C)
midiOut(0xB0:0x4E:0x1D) # B : A2 side
midiOut(0xB1:0x4E:0x1D)
# turn off LEDs
BlinkSet(~deck_a_cue_led,0)
BlinkSet(~deck_b_cue_led,0)
BlinkSet(~deck_a_playpause_led,0)
BlinkSet(~deck_b_playpause_led,0)
BlinkSet(~deck_a_jog_mode_led,0)
BlinkSet(~deck_b_jog_mode_led,0)
BlinkSet(~deck_a_jog_led,0)
BlinkSet(~deck_b_jog_led,0)
BlinkSet(~deck_a_touch_dot,0)
BlinkSet(~deck_b_touch_dot,0)
BlinkSet(~deck_a_fx_1_led,0)
BlinkSet(~deck_b_fx_1_led,0)
BlinkSet(~deck_a_fx_2_led,0)
BlinkSet(~deck_b_fx_2_led,0)
BlinkSet(~deck_a_fx_3_led,0)
BlinkSet(~deck_b_fx_3_led,0)
BlinkSet(~deck_a_func_1_led,0)
BlinkSet(~deck_b_func_1_led,0)
BlinkSet(~deck_a_func_2_led,0)
BlinkSet(~deck_b_func_2_led,0)
BlinkSet(~deck_a_func_3_led,0)
BlinkSet(~deck_b_func_3_led,0)
BlinkSet(~deck_a_func_4_led,0)
BlinkSet(~deck_b_func_4_led,0)
BlinkSet(~deck_a_func_5_led,0)
BlinkSet(~deck_b_func_5_led,0)
BlinkSet(~deck_a_playlist_led,0)
BlinkSet(~deck_b_playlist_led,0)
BlinkSet(~deck_a_parameter_led,0)
BlinkSet(~deck_b_parameter_led,0)
# set slider mode LEDs (starts in Tempo mode)
BlinkSet(~deck_a_slider_led_green,1)
BlinkSet(~deck_a_slider_led_orange,0)
BlinkSet(~deck_b_slider_led_green,1)
BlinkSet(~deck_b_slider_led_orange,0)
# set default time display mode (currently 0 from declaration)
VarSet($deck_a_time_mode,0) # elapsed
VarSet($deck_b_time_mode,0) # elapsed
# set default jog mode (currently 0 from declaration)
VarSet($deck_a_jog_mode,0) # bend
VarSet($deck_b_jog_mode,0) # bend
# update screens
midi.HC4500.TextSet(A,D)
midi.HC4500.TextSet(B,D)
midi.HC4500.Time(A,D,0)
midi.HC4500.Time(B,D,0)
midi.HC4500.Rotation(A,D)
midi.HC4500.Rotation(B,D)
midi.HC4500.Progress(A,D)
midi.HC4500.Progress(B,D)
midi.HC4500.BPM(A,D)
midi.HC4500.BPM(B,D)
midi.HC4500.Slider(A,E,0) # enable in tempo mode
midi.HC4500.Slider(B,E,0)
# get current OtsAV state
avStateRequest() # will generate appropriate Load, Play, etc events
# get state of controller sliders
midiOut(0xB0:0x4A:0x3C) # deck A slider request
midiOut(0xB1:0x4A:0x3C) # deck B slider request
# activate video master functionality
avVideoMaster(E)
}
# ******* Respond to OtsAV/other events *******
########################################################
####### Deck A: Load/Cue/Play-Pause/Frame Search/etc
av[Load,A,E] { # Deck A Load (entered Loaded state)
VarSet($deck_a_loaded,1) # save state for our own use
BlinkSet(~deck_a_playpause_led,3) # medium blink
midi.HC4500.TextSet(A,E)
($deck_a_time_mode=0) midi.HC4500.Time(A,E,0)
($deck_a_time_mode=1) midi.HC4500.Time(A,E,1)
midi.HC4500.Rotation(A,E)
midi.HC4500.Progress(A,E)
midi.HC4500.BPM(A,E)
}
av[Load,A,D] { # Deck A Eject (left Loaded state)
VarSet($deck_a_loaded,0) # clear state
BlinkSet(~deck_a_playpause_led,0) # off
midi.HC4500.TextSet(A,D)
midi.HC4500.Time(A,D,0)
midi.HC4500.Rotation(A,D)
midi.HC4500.Progress(A,D)
midi.HC4500.BPM(A,D)
}
av[Play,A,E] { # Deck A Play (entered Playing state)
VarSet($deck_a_playing,1) # save state for our own use
BlinkSet(~deck_a_playpause_led,1) # on
}
av[Play,A,D] { # Deck A Stop (left Playing state)
VarSet($deck_a_playing,0) # clear state
BlinkSet(~deck_a_playpause_led,3) # medium blink
}
av[Cued,A,E] { # Deck A entered Cued state
BlinkSet(~deck_a_cue_led,1) # on
}
av[Cued,A,D] { # Deck A left Cued state
BlinkSet(~deck_a_cue_led,0) # off
}
av[PreMix,A,E] { # Deck A entered Pre-mix state
BlinkSet(~deck_a_playpause_led,4) # fast blink
}
av[PreMix,A,D] { # Deck A left Pre-mix state
BlinkSet(~deck_a_playpause_led,3) # medium blink
}
av[FrameSearch,A,E] { # Deck A entered Frame Search mode
VarSet($deck_a_frame_search,1) # save state for our own use
VarSet($deck_a_search_spin_counter,40)
BlinkSet(~deck_a_cue_led,4) # fast blink
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[FrameSearch,A,D] { # Deck A left Frame Search mode
VarSet($deck_a_frame_search,0) # clear state
BlinkSet(~deck_a_cue_led,0) # off
}
av[CuePointSet,A] midi.HC4500.TextMsgSet(A,E,10,"")
####### Deck B: Load/Cue/Play-Pause/Frame Search/etc
av[Load,B,E] { # Deck B Load (entered Loaded state)
VarSet($deck_b_loaded,1) # save state for our own use
BlinkSet(~deck_b_playpause_led,3) # medium blink
midi.HC4500.TextSet(B,E)
($deck_b_time_mode=0) midi.HC4500.Time(B,E,0)
($deck_b_time_mode=1) midi.HC4500.Time(B,E,1)
midi.HC4500.Rotation(B,E)
midi.HC4500.Progress(B,E)
midi.HC4500.BPM(B,E)
}
av[Load,B,D] { # Deck B Eject (left Loaded state)
VarSet($deck_b_loaded,0) # clear state
BlinkSet(~deck_b_playpause_led,0) # off
midi.HC4500.TextSet(B,D)
midi.HC4500.Time(B,D,0)
midi.HC4500.Rotation(B,D)
midi.HC4500.Progress(B,D)
midi.HC4500.BPM(B,D)
}
av[Play,B,E] { # Deck B Play (entered Playing state)
VarSet($deck_b_playing,1) # save state for our own use
BlinkSet(~deck_b_playpause_led,1) # on
}
av[Play,B,D] { # Deck B Stop (left Playing state)
VarSet($deck_b_playing,0) # clear state
BlinkSet(~deck_b_playpause_led,3) # medium blink
}
av[Cued,B,E] { # Deck B entered Cued state
BlinkSet(~deck_b_cue_led,1) # on
}
av[Cued,B,D] { # Deck B left Cued state
BlinkSet(~deck_b_cue_led,0) # off
}
av[PreMix,B,E] { # Deck B entered Pre-mix state
BlinkSet(~deck_b_playpause_led,4) # fast blink
}
av[PreMix,B,D] { # Deck B left Pre-mix state
BlinkSet(~deck_b_playpause_led,3) # medium blink
}
av[FrameSearch,B,E] { # Deck B entered Frame Search mode
VarSet($deck_b_frame_search,1) # save state for our own use
VarSet($deck_b_search_spin_counter,40)
BlinkSet(~deck_b_cue_led,4) # fast blink
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[FrameSearch,B,D] { # Deck B left Frame Search mode
VarSet($deck_b_frame_search,0) # clear state
BlinkSet(~deck_b_cue_led,0) # off
}
av[CuePointSet,B] midi.HC4500.TextMsgSet(B,E,10,"")
########################################################
####### Deck A: Primary transport controls
midi.trigger[0x90:0x43:0x40] { # Deck A Play/Pause button down
($global_shift=0) avPlayPause(A,E)
($global_shift=1) avPlay(A)
}
midi.trigger[0x80:0x43:0x00] { # Deck A Play/Pause button up
avPlayPause(A,D)
}
midi.trigger[0x90:0x42:0x40] { # Deck A Cue button down
($global_shift=0) SubCall(@deck_a_cue_no_shift)
($global_shift=1) avCueSet(A)
}
sub[@deck_a_cue_no_shift] { # Deck A Cue button down without shift
($deck_a_scratch=0) avCue(A,E)
($deck_a_scratch=1) avCueSet(A)
}
midi.trigger[0x80:0x42:0x00] { # Deck A Cue button up
avCue(A,D)
}
midi.trigger[0x90:0x11:0x40] { # Deck A Frame Search (back) button down
($deck_a_mod=0) avFrameSearch(A,-1)
}
midi.trigger[0x90:0x10:0x40] { # Deck A Frame Search (forward) button down
($deck_a_mod=0) avFrameSearch(A,+1)
}
midi.relval[0xB0:0x51,0x00,0xC0,0x40] ($deck_a_frame_search=1) VarDec($deck_a_search_spin_counter)
midi.relval[0xB0:0x51,0x40,0xC0,0x40] ($deck_a_frame_search=1) VarInc($deck_a_search_spin_counter)
var.set[$deck_a_search_spin_counter=0] {
($deck_a_search_rate=0) avFrameSearch(A,-1)
($deck_a_search_rate=1) avFrameSearch(A,-5)
($deck_a_search_rate=2) avFrameSearch(A,-20)
VarInc($deck_a_search_rate)
VarSet($deck_a_search_spin_counter,80)
}
var.set[$deck_a_search_spin_counter=81] {
($deck_a_search_rate=0) avFrameSearch(A,+1)
($deck_a_search_rate=1) avFrameSearch(A,+5)
($deck_a_search_rate=2) avFrameSearch(A,+20)
VarInc($deck_a_search_rate)
VarSet($deck_a_search_spin_counter,1)
}
timer.tick VarDec($deck_a_search_rate)
####### Deck B: Primary transport controls
midi.trigger[0x91:0x43:0x40] { # Deck B Play/Pause button down
($global_shift=0) avPlayPause(B,E)
($global_shift=1) avPlay(B)
}
midi.trigger[0x81:0x43:0x00] { # Deck B Play/Pause button up
avPlayPause(B,D)
}
midi.trigger[0x91:0x42:0x40] { # Deck B Cue button down
($global_shift=0) SubCall(@deck_b_cue_no_shift)
($global_shift=1) avCueSet(B)
}
sub[@deck_b_cue_no_shift] { # Deck B Cue button down without shift
($deck_b_scratch=0) avCue(B,E)
($deck_b_scratch=1) avCueSet(B)
}
midi.trigger[0x81:0x42:0x00] { # Deck B Cue button up
avCue(B,D)
}
midi.trigger[0x91:0x11:0x40] { # Deck B Frame Search (back) button down
avFrameSearch(B,-1)
}
midi.trigger[0x91:0x10:0x40] { # Deck B Frame Search (forward) button down
avFrameSearch(B,+1)
}
midi.relval[0xB1:0x51,0x00,0xC0,0x40] ($deck_b_frame_search=1) VarDec($deck_b_search_spin_counter)
midi.relval[0xB1:0x51,0x40,0xC0,0x40] ($deck_b_frame_search=1) VarInc($deck_b_search_spin_counter)
var.set[$deck_b_search_spin_counter=0] {
($deck_b_search_rate=0) avFrameSearch(B,-1)
($deck_b_search_rate=1) avFrameSearch(B,-5)
($deck_b_search_rate=2) avFrameSearch(B,-20)
VarInc($deck_b_search_rate)
VarSet($deck_b_search_spin_counter,80)
}
var.set[$deck_b_search_spin_counter=81] {
($deck_b_search_rate=0) avFrameSearch(B,+1)
($deck_b_search_rate=1) avFrameSearch(B,+5)
($deck_b_search_rate=2) avFrameSearch(B,+20)
VarInc($deck_b_search_rate)
VarSet($deck_b_search_spin_counter,1)
}
timer.tick VarDec($deck_b_search_rate)
########################################################
####### Deck A: Shift key
midi.trigger[0x90:0x30:0x40] VarSet($deck_a_shift,1)
midi.trigger[0x80:0x30:0x00] VarSet($deck_a_shift,0)
####### Deck B: Shift key
midi.trigger[0x91:0x30:0x40] VarSet($deck_b_shift,1)
midi.trigger[0x81:0x30:0x00] VarSet($deck_b_shift,0)
####### Global Shift state
var.set[$deck_a_shift=1] {
VarSet($global_shift,1)
($deck_b_shift=1) avNext() # "mix now" when both shifts pressed
}
var.set[$deck_a_shift=0] ($deck_b_shift=0) VarSet($global_shift,0)
var.set[$deck_b_shift=1] {
VarSet($global_shift,1)
($deck_a_shift=1) avNext() # "mix now" when both shifts pressed
}
var.set[$deck_b_shift=0] ($deck_a_shift=0) VarSet($global_shift,0)
########################################################
####### Deck A: Time display
midi.trigger[0x90:0x23:0x40] { # Deck A Time button down
VarIncWrap($deck_a_time_mode)
}
var.set[$deck_a_time_mode=0] ($deck_a_loaded=1) midi.HC4500.Time(A,E,0)
var.set[$deck_a_time_mode=1] ($deck_a_loaded=1) midi.HC4500.Time(A,E,1)
####### Deck B: Time display
midi.trigger[0x91:0x23:0x40] { # Deck B Time button down
VarIncWrap($deck_b_time_mode)
}
var.set[$deck_b_time_mode=0] ($deck_b_loaded=1) midi.HC4500.Time(B,E,0)
var.set[$deck_b_time_mode=1] ($deck_b_loaded=1) midi.HC4500.Time(B,E,1)
########################################################
####### Deck A: High-precision BPM display
midi.trigger[0x90:0x24:0x40] { # Deck A Memo button down
($deck_a_loaded=1) midi.HC4500.TextMsg.BPM(A,20)
}
av[BPMChanged,A] midi.HC4500.TextMsg.BPM(A,20)
####### Deck B: High-precision BPM display
midi.trigger[0x91:0x24:0x40] { # Deck B Memo button down
($deck_b_loaded=1) midi.HC4500.TextMsg.BPM(B,20)
}
av[BPMChanged,B] midi.HC4500.TextMsg.BPM(B,20)
########################################################
####### Deck A: Jog mode/Bending/Scratching
midi.trigger[0x90:0x04:0x40] { # Deck A Jog Mode button down
($deck_a_frame_search=0) VarIncWrap($deck_a_jog_mode)
}
var.set[$deck_a_jog_mode=0] {
($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled
BlinkSet(~deck_a_jog_mode_led,0)
($deck_a_playing=1) BlinkSet(~deck_a_jog_led,2) # slow blink
midi.HC4500.TextMsgSet(A,E,10,"")
}
var.set[$deck_a_jog_mode=1] {
($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled
BlinkSet(~deck_a_jog_mode_led,1)
($deck_a_playing=1) BlinkSet(~deck_a_jog_led,3) # medium blink
($deck_a_zorphing=0) midi.HC4500.TextMsgSet(A,E,10,"")
($deck_a_zorphing=1) midi.HC4500.TextMsgSet(A,E,10,"")
}
var.set[$deck_a_playing=1] { # Deck A Play (entered Playing state)
($deck_a_jog_mode=0) BlinkSet(~deck_a_jog_led,2) # slow blink
($deck_a_jog_mode=1) BlinkSet(~deck_a_jog_led,3) # medium blink
}
var.set[$deck_a_playing=0] { # Deck A Stop (left Playing state)
($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled
($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled
($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled
($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled
BlinkSet(~deck_a_jog_led,0) # off
}
var.set[$deck_a_frame_search=1] { # Deck A entered Frame Search mode
($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled
($deck_a_scratch=1) VarSet($deck_a_scratch,0) # cancel scratching if enabled
BlinkSet(~deck_a_jog_led,7) # pulse mode 3
}
var.set[$deck_a_frame_search=0] { # Deck A left Frame Search mode
($deck_a_jog_mode=0) BlinkSet(~deck_a_jog_led,2) # slow blink
($deck_a_jog_mode=1) BlinkSet(~deck_a_jog_led,3) # medium blink
}
midi.trigger[0x90:0x51:0x40] { # Deck A Jog button down
VarSet($deck_a_jog_button,1)
}
var.set[$deck_a_jog_button=1] {
($deck_a_jog_mode=1) SubCall(@deck_a_try_scratch)
}
sub[@deck_a_try_scratch] ($deck_a_playing=1) SubCall(@deck_a_try_scratch2)
sub[@deck_a_try_scratch2] {
($deck_a_frame_search=0) VarSet($deck_a_scratch,1)
($deck_a_frame_search=0) VarSet($deck_a_touch_dot,1)
}
midi.trigger[0x80:0x51:0x00] { # Deck A Jog button up
VarSet($deck_a_jog_button,0)
}
var.set[$deck_a_jog_button=0] {
($deck_a_scratch_state!=1) VarSet($deck_a_scratch,0) # cancel scratching if jog inactive
VarSet($deck_a_touch_dot,0)
}
var.set[$deck_a_scratch=1] {
avScratch(A,E,0.0)
BlinkSet(~deck_a_cue_led,4) # fast blink
}
var.set[$deck_a_scratch=0] {
avScratch(A,D,0.0)
BlinkSet(~deck_a_cue_led,0)
}
var.set[$deck_a_touch_dot=0] BlinkSet(~deck_a_touch_dot,0)
var.set[$deck_a_touch_dot=1] BlinkSet(~deck_a_touch_dot,1)
sub[@deck_a_try_bend] ($deck_a_frame_search=0) VarSet($deck_a_bend,1)
var.set[$deck_a_bend=1] {
($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled
($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled
avBend(A,E,0.0)
}
var.set[$deck_a_bend=0] {
avBend(A,D,0.0)
}
midi.velval[R,0xB0:0x51,0x40,0x40,0,1.2,0.1,$deck_a_bend_state,0] ($deck_a_jog_mode=0) SubCall(@deck_a_jog_val_bend)
midi.velval[R,0xB0:0x51,0x40,0x40,0,0.5,0.2,$deck_a_scratch_state,0] ($deck_a_jog_mode=1) SubCall(@deck_a_jog_val_scratch)
sub[@deck_a_jog_val_bend] { # new value from jog wheel
($deck_a_bend=1) avBendSet(A,_)
}
var.set[$deck_a_bend_state!=0] { # jog wheel active in bending mode
($deck_a_playing=1) SubCall(@deck_a_try_bend)
}
var.set[$deck_a_bend_state=0] { # jog wheel inactive in bending mode
VarSet($deck_a_bend,0) # cancel bending
}
sub[@deck_a_jog_val_scratch] { # new value from jog wheel
($deck_a_scratch=1) avScratchSet(A,_)
}
var.set[$deck_a_scratch_state!=1] { # jog wheel inactive in scratching mode
($deck_a_jog_button=0) VarSet($deck_a_scratch,0) # cancel scratching if jog button not down
}
midi.trigger[0x90:0x09:0x40] ($deck_a_playing=1) VarSet($deck_a_bend_down,1)
midi.trigger[0x80:0x09:0x00] ($deck_a_bend_down=1) VarSet($deck_a_bend_down,0)
midi.trigger[0x90:0x08:0x40] ($deck_a_playing=1) VarSet($deck_a_bend_up,1)
midi.trigger[0x80:0x08:0x00] ($deck_a_bend_up=1) VarSet($deck_a_bend_up,0)
var.set[$deck_a_bend_down=1] {
($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled
($deck_a_bend_up=1) VarSet($deck_a_bend_up,0) # cancel bend up if enabled
avBend(A,E,-0.4) # bend down at 4%
}
var.set[$deck_a_bend_down=0] {
avBend(A,D,0.0) # cancel bend down
}
var.set[$deck_a_bend_up=1] {
($deck_a_bend=1) VarSet($deck_a_bend,0) # cancel bending if enabled
($deck_a_bend_down=1) VarSet($deck_a_bend_down,0) # cancel bend down if enabled
avBend(A,E,+0.4) # bend up at 4%
}
var.set[$deck_a_bend_up=0] {
avBend(A,D,0.0) # cancel bend up
}
midi.trigger[0x90:0x17:0x40] avBendTempoModeSet(A,T)
av[BendTempoMode,A,D] {
VarSet($deck_a_bend_tempo,0)
($abm_active=0) BlinkSet(~deck_a_func_1_led,0)
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[BendTempoMode,A,E] {
VarSet($deck_a_bend_tempo,1)
($abm_active=0) BlinkSet(~deck_a_func_1_led,1)
midi.HC4500.TextMsgSet(A,E,10,"")
}
midi.trigger[0x90:0x18:0x40] avZorphingModeSet(A,T)
av[ZorphingMode,A,D] {
VarSet($deck_a_zorphing,0)
($abm_active=0) BlinkSet(~deck_a_func_2_led,0)
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[ZorphingMode,A,E] {
VarSet($deck_a_zorphing,1)
($abm_active=0) BlinkSet(~deck_a_func_2_led,3) # medium blink
midi.HC4500.TextMsgSet(A,E,10,"")
}
####### Deck B: Jog mode/Bending/Scratching
midi.trigger[0x91:0x04:0x40] { # Deck B Jog Mode button down
($deck_b_frame_search=0) VarIncWrap($deck_b_jog_mode)
}
var.set[$deck_b_jog_mode=0] {
($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled
BlinkSet(~deck_b_jog_mode_led,0)
($deck_b_playing=1) BlinkSet(~deck_b_jog_led,2) # slow blink
midi.HC4500.TextMsgSet(B,E,10,"")
}
var.set[$deck_b_jog_mode=1] {
($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled
BlinkSet(~deck_b_jog_mode_led,1)
($deck_b_playing=1) BlinkSet(~deck_b_jog_led,3) # medium blink
($deck_b_zorphing=0) midi.HC4500.TextMsgSet(B,E,10,"")
($deck_b_zorphing=1) midi.HC4500.TextMsgSet(B,E,10,"")
}
var.set[$deck_b_playing=1] { # Deck B Play (entered Playing state)
($deck_b_jog_mode=0) BlinkSet(~deck_b_jog_led,2) # slow blink
($deck_b_jog_mode=1) BlinkSet(~deck_b_jog_led,3) # medium blink
}
var.set[$deck_b_playing=0] { # Deck B Stop (left Playing state)
($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled
($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled
($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled
($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled
BlinkSet(~deck_b_jog_led,0) # off
}
var.set[$deck_b_frame_search=1] { # Deck B entered Frame Search mode
($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled
($deck_b_scratch=1) VarSet($deck_b_scratch,0) # cancel scratching if enabled
BlinkSet(~deck_b_jog_led,7) # pulse mode 3
}
var.set[$deck_b_frame_search=0] { # Deck B left Frame Search mode
($deck_b_jog_mode=0) BlinkSet(~deck_b_jog_led,2) # slow blink
($deck_b_jog_mode=1) BlinkSet(~deck_b_jog_led,3) # medium blink
}
midi.trigger[0x91:0x51:0x40] { # Deck B Jog button down
VarSet($deck_b_jog_button,1)
}
var.set[$deck_b_jog_button=1] {
($deck_b_jog_mode=1) SubCall(@deck_b_try_scratch)
}
sub[@deck_b_try_scratch] ($deck_b_playing=1) SubCall(@deck_b_try_scratch2)
sub[@deck_b_try_scratch2] {
($deck_b_frame_search=0) VarSet($deck_b_scratch,1)
($deck_b_frame_search=0) VarSet($deck_b_touch_dot,1)
}
midi.trigger[0x81:0x51:0x00] { # Deck B Jog button up
VarSet($deck_b_jog_button,0)
}
var.set[$deck_b_jog_button=0] {
($deck_b_scratch_state!=1) VarSet($deck_b_scratch,0) # cancel scratching if jog inactive
VarSet($deck_b_touch_dot,0)
}
var.set[$deck_b_scratch=1] {
avScratch(B,E,0.0)
BlinkSet(~deck_b_cue_led,4) # fast blink
}
var.set[$deck_b_scratch=0] {
avScratch(B,D,0.0)
BlinkSet(~deck_b_cue_led,0)
}
var.set[$deck_b_touch_dot=0] BlinkSet(~deck_b_touch_dot,0)
var.set[$deck_b_touch_dot=1] BlinkSet(~deck_b_touch_dot,1)
sub[@deck_b_try_bend] ($deck_b_frame_search=0) VarSet($deck_b_bend,1)
var.set[$deck_b_bend=1] {
($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled
($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled
avBend(B,E,0.0)
}
var.set[$deck_b_bend=0] {
avBend(B,D,0.0)
}
midi.velval[R,0xB1:0x51,0x40,0x40,0,1.2,0.1,$deck_b_bend_state,0] ($deck_b_jog_mode=0) SubCall(@deck_b_jog_val_bend)
midi.velval[R,0xB1:0x51,0x40,0x40,0,0.5,0.2,$deck_b_scratch_state,0] ($deck_b_jog_mode=1) SubCall(@deck_b_jog_val_scratch)
sub[@deck_b_jog_val_bend] { # new value from jog wheel
($deck_b_bend=1) avBendSet(B,_)
}
var.set[$deck_b_bend_state!=0] { # jog wheel active in bending mode
($deck_b_playing=1) SubCall(@deck_b_try_bend)
}
var.set[$deck_b_bend_state=0] { # jog wheel inactive in bending mode
VarSet($deck_b_bend,0) # cancel bending
}
sub[@deck_b_jog_val_scratch] { # new value from jog wheel
($deck_b_scratch=1) avScratchSet(B,_)
}
var.set[$deck_b_scratch_state!=1] { # jog wheel inactive in scratching mode
($deck_b_jog_button=0) VarSet($deck_b_scratch,0) # cancel scratching if jog button not down
}
midi.trigger[0x91:0x09:0x40] ($deck_b_playing=1) VarSet($deck_b_bend_down,1)
midi.trigger[0x81:0x09:0x00] ($deck_b_bend_down=1) VarSet($deck_b_bend_down,0)
midi.trigger[0x91:0x08:0x40] ($deck_b_playing=1) VarSet($deck_b_bend_up,1)
midi.trigger[0x81:0x08:0x00] ($deck_b_bend_up=1) VarSet($deck_b_bend_up,0)
var.set[$deck_b_bend_down=1] {
($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled
($deck_b_bend_up=1) VarSet($deck_b_bend_up,0) # cancel bend up if enabled
avBend(B,E,-0.4) # bend down at 4%
}
var.set[$deck_b_bend_down=0] {
avBend(B,D,0.0) # cancel bend down
}
var.set[$deck_b_bend_up=1] {
($deck_b_bend=1) VarSet($deck_b_bend,0) # cancel bending if enabled
($deck_b_bend_down=1) VarSet($deck_b_bend_down,0) # cancel bend down if enabled
avBend(B,E,+0.4) # bend up at 4%
}
var.set[$deck_b_bend_up=0] {
avBend(B,D,0.0) # cancel bend up
}
midi.trigger[0x91:0x17:0x40] avBendTempoModeSet(B,T)
av[BendTempoMode,B,D] {
VarSet($deck_b_bend_tempo,0)
($abm_active=0) BlinkSet(~deck_b_func_1_led,0)
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[BendTempoMode,B,E] {
VarSet($deck_b_bend_tempo,1)
($abm_active=0) BlinkSet(~deck_b_func_1_led,1)
midi.HC4500.TextMsgSet(B,E,10,"")
}
midi.trigger[0x91:0x18:0x40] avZorphingModeSet(B,T)
av[ZorphingMode,B,D] {
VarSet($deck_b_zorphing,0)
($abm_active=0) BlinkSet(~deck_b_func_2_led,0)
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[ZorphingMode,B,E] {
VarSet($deck_b_zorphing,1)
($abm_active=0) BlinkSet(~deck_b_func_2_led,3) # medium blink
midi.HC4500.TextMsgSet(B,E,10,"")
}
########################################################
####### Deck A: Bass/Mid/High cut
midi.trigger[0x90:0x12:0x40] { # Deck A FX-1 button down
avEQCutBass(A,T) # Toggle Deck A Bass Cut
}
midi.trigger[0x90:0x13:0x40] { # Deck A FX-2 button down
avEQCutMid(A,T) # Toggle Deck A Mid Cut
}
midi.trigger[0x90:0x14:0x40] { # Deck A FX-3 button down
avEQCutHigh(A,T) # Toggle Deck A High Cut
}
av[EQCutBass,A,E] { # Deck A Bass Cut enabled
BlinkSet(~deck_a_fx_1_led,1)
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[EQCutBass,A,D] { # Deck A Bass Cut disabled
BlinkSet(~deck_a_fx_1_led,0)
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[EQCutMid,A,E] { # Deck A Mid Cut enabled
BlinkSet(~deck_a_fx_2_led,1)
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[EQCutMid,A,D] { # Deck A Mid Cut disabled
BlinkSet(~deck_a_fx_2_led,0)
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[EQCutHigh,A,E] { # Deck A High Cut enabled
BlinkSet(~deck_a_fx_3_led,1)
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[EQCutHigh,A,D] { # Deck A High Cut disabled
BlinkSet(~deck_a_fx_3_led,0)
midi.HC4500.TextMsgSet(A,E,10,"")
}
####### Deck B: Bass/Mid/High cut
midi.trigger[0x91:0x12:0x40] { # Deck B FX-1 button down
avEQCutBass(B,T) # Toggle Deck B Bass Cut
}
midi.trigger[0x91:0x13:0x40] { # Deck B FX-2 button down
avEQCutMid(B,T) # Toggle Deck B Mid Cut
}
midi.trigger[0x91:0x14:0x40] { # Deck B FX-3 button down
avEQCutHigh(B,T) # Toggle Deck B High Cut
}
av[EQCutBass,B,E] { # Deck B Bass Cut enabled
BlinkSet(~deck_b_fx_1_led,1)
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[EQCutBass,B,D] { # Deck B Bass Cut disabled
BlinkSet(~deck_b_fx_1_led,0)
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[EQCutMid,B,E] { # Deck B Mid Cut enabled
BlinkSet(~deck_b_fx_2_led,1)
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[EQCutMid,B,D] { # Deck B Mid Cut disabled
BlinkSet(~deck_b_fx_2_led,0)
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[EQCutHigh,B,E] { # Deck B High Cut enabled
BlinkSet(~deck_b_fx_3_led,1)
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[EQCutHigh,B,D] { # Deck B High Cut disabled
BlinkSet(~deck_b_fx_3_led,0)
midi.HC4500.TextMsgSet(B,E,10,"")
}
########################################################
####### Deck A: Slider/slider mode/slider range
midi.absval[D,0xE0,1,7,0x7F7F,0x0040,0x0000] SubCall(@deck_a_slider_val)
sub[@deck_a_slider_val] { # new value from slider
($deck_a_slider_index=0) SubCall(@deck_a_slider_val_tempo)
($deck_a_slider_index=1) SubCall(@deck_a_slider_val_pitch)
($deck_a_slider_index=2) SubCall(@deck_a_slider_val_direction)
}
sub[@deck_a_slider_val_tempo] { # slider pos -- tempo
($global_shift=0) avTempoSet(A,_) # normal sync logic
($global_shift=1) avTempoSet(A,_,F1) # force synced state
}
sub[@deck_a_slider_val_pitch] { # slider pos -- pitch
($global_shift=0) avPitchSet(A,_) # normal sync logic
($global_shift=1) avPitchSet(A,_,F1) # force synced state
}
sub[@deck_a_slider_val_direction] { # slider pos -- direction
($global_shift=0) avDirectionSet(A,_) # normal sync logic
($global_shift=1) avDirectionSet(A,_,F0|F4) # bypass sync logic and snap value
}
midi.trigger[0x90:0x05:0x40] { # slider mode/range button down
VarSet($deck_a_slider_button_count,1)
}
midi.trigger[0x80:0x05:0x00] { # slider mode/range button up
($deck_a_slider_button_count!=0) VarIncWrap($deck_a_slider_index)
VarSet($deck_a_slider_button_count,0)
}
timer.tick ($deck_a_slider_button_count!=0) VarInc($deck_a_slider_button_count)
var.set[$deck_a_slider_button_count=8] { # cycle to next range
VarSet($deck_a_slider_button_count,0)
($deck_a_slider_index=0) avSliderRangeSet.Tempo(A,0)
($deck_a_slider_index=1) avSliderRangeSet.Pitch(A,0)
}
sub[@deck_a_slider_info] {
($deck_a_slider_index=0) midi.HC4500.TextMsgSet(A,E,20,"")
($deck_a_slider_index=0) midi.HC4500.TextMsg.SliderRange.Tempo(A,20,F1)
($deck_a_slider_index=1) midi.HC4500.TextMsgSet(A,E,20,"")
($deck_a_slider_index=1) midi.HC4500.TextMsg.SliderRange.Pitch(A,20,F1)
($deck_a_slider_index=2) midi.HC4500.TextMsgSet(A,E,10,"")
($deck_a_slider_index=2) midi.HC4500.TextMsgSet(A,E,10,F1,"")
}
var.set[$deck_a_slider_index=0] { # Tempo
avTempoSet(A,0.0,F2|F6|F7) # init sync from Direction
midi.HC4500.Slider(A,E,0)
BlinkSet(~deck_a_slider_led_green,1)
BlinkSet(~deck_a_slider_led_orange,0)
SubCall(@deck_a_slider_info)
avPitchSet(A,0.0,F5) # force pitch slider to be visible (would be direction)
}
var.set[$deck_a_slider_index=1] { # Pitch
avPitchSet(A,0.0,F2|F6) # init sync from Tempo
midi.HC4500.Slider(A,E,1)
BlinkSet(~deck_a_slider_led_green,0)
BlinkSet(~deck_a_slider_led_orange,1)
SubCall(@deck_a_slider_info)
}
var.set[$deck_a_slider_index=2] { # Direction
avDirectionSet(A,0.0,F2|F7) # init sync from Pitch
midi.HC4500.Slider(A,E,2)
BlinkSet(~deck_a_slider_led_green,4) # fast blink
BlinkSet(~deck_a_slider_led_orange,12) # inverse fast blink
SubCall(@deck_a_slider_info)
}
av[SliderRangeNew.Tempo,A] {
($deck_a_slider_index=0) avTempoSet(A,0.0,F2|F6) # init sync from Tempo
($deck_a_slider_index=0) SubCall(@deck_a_slider_info)
}
av[SliderRangeNew.Pitch,A] {
($deck_a_slider_index=1) avPitchSet(A,0.0,F2|F7) # init sync from Pitch
($deck_a_slider_index=1) SubCall(@deck_a_slider_info)
}
midi.trigger[0x90:0x07:0x40] {
($deck_a_shift=1) avBPMMatch.Tempo(A)
}
####### Deck B: Slider/slider mode/slider range
midi.absval[D,0xE1,1,7,0x7F7F,0x0040,0x0000] SubCall(@deck_b_slider_val)
sub[@deck_b_slider_val] { # new value from slider
($deck_b_slider_index=0) SubCall(@deck_b_slider_val_tempo)
($deck_b_slider_index=1) SubCall(@deck_b_slider_val_pitch)
($deck_b_slider_index=2) SubCall(@deck_b_slider_val_direction)
}
sub[@deck_b_slider_val_tempo] { # slider pos -- tempo
($global_shift=0) avTempoSet(B,_) # normal sync logic
($global_shift=1) avTempoSet(B,_,F1) # force synced state
}
sub[@deck_b_slider_val_pitch] { # slider pos -- pitch
($global_shift=0) avPitchSet(B,_) # normal sync logic
($global_shift=1) avPitchSet(B,_,F1) # force synced state
}
sub[@deck_b_slider_val_direction] { # slider pos -- direction
($global_shift=0) avDirectionSet(B,_) # normal sync logic
($global_shift=1) avDirectionSet(B,_,F0|F4) # bypass sync logic and snap value
}
midi.trigger[0x91:0x05:0x40] { # slider mode/range button down
VarSet($deck_b_slider_button_count,1)
}
midi.trigger[0x81:0x05:0x00] { # slider mode/range button up
($deck_b_slider_button_count!=0) VarIncWrap($deck_b_slider_index)
VarSet($deck_b_slider_button_count,0)
}
timer.tick ($deck_b_slider_button_count!=0) VarInc($deck_b_slider_button_count)
var.set[$deck_b_slider_button_count=8] { # cycle to next range
VarSet($deck_b_slider_button_count,0)
($deck_b_slider_index=0) avSliderRangeSet.Tempo(B,0)
($deck_b_slider_index=1) avSliderRangeSet.Pitch(B,0)
}
sub[@deck_b_slider_info] {
($deck_b_slider_index=0) midi.HC4500.TextMsgSet(B,E,20,"")
($deck_b_slider_index=0) midi.HC4500.TextMsg.SliderRange.Tempo(B,20,F1)
($deck_b_slider_index=1) midi.HC4500.TextMsgSet(B,E,20,"")
($deck_b_slider_index=1) midi.HC4500.TextMsg.SliderRange.Pitch(B,20,F1)
($deck_b_slider_index=2) midi.HC4500.TextMsgSet(B,E,10,"")
($deck_b_slider_index=2) midi.HC4500.TextMsgSet(B,E,10,F1,"")
}
var.set[$deck_b_slider_index=0] { # Tempo
avTempoSet(B,0.0,F2|F6|F7) # init sync from Direction
midi.HC4500.Slider(B,E,0)
BlinkSet(~deck_b_slider_led_green,1)
BlinkSet(~deck_b_slider_led_orange,0)
SubCall(@deck_b_slider_info)
avPitchSet(B,0.0,F5) # force pitch slider to be visible (would be direction)
}
var.set[$deck_b_slider_index=1] { # Pitch
avPitchSet(B,0.0,F2|F6) # init sync from Tempo
midi.HC4500.Slider(B,E,1)
BlinkSet(~deck_b_slider_led_green,0)
BlinkSet(~deck_b_slider_led_orange,1)
SubCall(@deck_b_slider_info)
}
var.set[$deck_b_slider_index=2] { # Direction
avDirectionSet(B,0.0,F2|F7) # init sync from Pitch
midi.HC4500.Slider(B,E,2)
BlinkSet(~deck_b_slider_led_green,4) # fast blink
BlinkSet(~deck_b_slider_led_orange,12) # inverse fast blink
SubCall(@deck_b_slider_info)
}
av[SliderRangeNew.Tempo,B] {
($deck_b_slider_index=0) avTempoSet(B,0.0,F2|F6) # init sync from Tempo
($deck_b_slider_index=0) SubCall(@deck_b_slider_info)
}
av[SliderRangeNew.Pitch,B] {
($deck_b_slider_index=1) avPitchSet(B,0.0,F2|F7) # init sync from Pitch
($deck_b_slider_index=1) SubCall(@deck_b_slider_info)
}
midi.trigger[0x91:0x07:0x40] {
($deck_b_shift=1) avBPMMatch.Tempo(B)
}
########################################################
####### Deck A: Video Block/Master functionality
midi.trigger[0x90:0x20:0x40] avVideoBlock(A,T) # toggle video block
av[VideoBlock,A,E] {
VarSet($deck_a_video_block,1)
($abm_active=0) BlinkSet(~deck_a_func_4_led,3) # medium blink
midi.HC4500.TextMsgSet(A,E,10,"")
}
av[VideoBlock,A,D] {
VarSet($deck_a_video_block,0)
($abm_active=0) BlinkSet(~deck_a_func_4_led,0)
midi.HC4500.TextMsgSet(A,E,10,"")
}
midi.trigger[0x90:0x21:0x40] { # Deck A Master Video (Func 5) button down
($video_master!=0) avVideoMasterSet(A) # set as video master
($video_master=0) avVideoMasterSet(B) # make other deck master
}
av[VideoMasterSet,A] {
VarSet($video_master,0)
($abm_active=0) BlinkSet(~deck_a_func_5_led,1)
($abm_active=0) BlinkSet(~deck_b_func_5_led,0)
}
####### Deck B: Video Block/Master functionality
midi.trigger[0x91:0x20:0x40] avVideoBlock(B,T) # toggle video block
av[VideoBlock,B,E] {
VarSet($deck_b_video_block,1)
($abm_active=0) BlinkSet(~deck_b_func_4_led,3) # medium blink
midi.HC4500.TextMsgSet(B,E,10,"")
}
av[VideoBlock,B,D] {
VarSet($deck_b_video_block,0)
($abm_active=0) BlinkSet(~deck_b_func_4_led,0)
midi.HC4500.TextMsgSet(B,E,10,"")
}
midi.trigger[0x91:0x21:0x40] { # Deck B Master Video (Func 5) button down
($video_master!=1) avVideoMasterSet(B) # set as video master
($video_master=1) avVideoMasterSet(A) # make other deck master
}
av[VideoMasterSet,B] {
VarSet($video_master,1)
($abm_active=0) BlinkSet(~deck_b_func_5_led,1)
($abm_active=0) BlinkSet(~deck_a_func_5_led,0)
}
########################################################
####### Playlist Navigation
midi.trigger[0x90:0x02:0x40] { # Deck A Playlist/Eject button down
VarSet($deck_a_playlist_button_count,1)
}
midi.trigger[0x91:0x02:0x40] { # Deck B Playlist/Eject button down
VarSet($deck_b_playlist_button_count,1)
}
midi.trigger[0x80:0x02:0x00] { # Deck A Playlist/Eject button up
($deck_a_playlist_button_count!=0) SubCall(@deck_a_playlist_button_up)
VarSet($deck_a_playlist_button_count,0)
}
midi.trigger[0x81:0x02:0x00] { # Deck B Playlist/Eject button up
($deck_b_playlist_button_count!=0) SubCall(@deck_b_playlist_button_up)
VarSet($deck_b_playlist_button_count,0)
}
timer.tick ($deck_a_playlist_button_count!=0) VarInc($deck_a_playlist_button_count)
timer.tick ($deck_b_playlist_button_count!=0) VarInc($deck_b_playlist_button_count)
var.set[$deck_a_playlist_button_count=21] { # eject
VarSet($deck_a_playlist_button_count,0)
($global_shift=0) avEject(A)
($global_shift=1) avEject(A,F1)
($deck_a_loaded=1) midi.HC4500.TextMsgSet(A,E,10,"")
}
var.set[$deck_b_playlist_button_count=21] { # eject
VarSet($deck_b_playlist_button_count,0)
($global_shift=0) avEject(B)
($global_shift=1) avEject(B,F1)
($deck_b_loaded=1) midi.HC4500.TextMsgSet(B,E,10,"")
}
sub[@deck_a_playlist_button_up] {
($global_shift=0) SubCall(@deck_a_playlist_nav)
($global_shift=1) Subcall(@deck_a_playlist_loadnext)
}
sub[@deck_b_playlist_button_up] {
($global_shift=0) SubCall(@deck_b_playlist_nav)
($global_shift=1) Subcall(@deck_b_playlist_loadnext)
}
sub[@deck_a_playlist_nav] {
($playlist_nav_activity=0) VarSet($playlist_nav_last_deck,0)
($playlist_nav_activity=0) avPlaylistNav(T)
($playlist_nav_activity=1) avPlaylistNav(D)
($playlist_nav_activity=1) VarSet($playlist_nav_activity,0)
}
sub[@deck_b_playlist_nav] {
($playlist_nav_activity=0) VarSet($playlist_nav_last_deck,1)
($playlist_nav_activity=0) avPlaylistNav(T)
($playlist_nav_activity=1) avPlaylistNav(D)
($playlist_nav_activity=1) VarSet($playlist_nav_activity,0)
}
midi.trigger[0xB0:0x54:0x7F] { # Deck A Parameter knob turned anti-clockwise
($playlist_nav=1) VarSet($playlist_nav_last_deck,0)
($playlist_nav=1) VarSet($playlist_nav_activity,1)
($playlist_nav=1) avPlaylistNav.Walk(+1)
}
midi.trigger[0xB1:0x54:0x7F] { # Deck B Parameter knob turned anti-clockwise
($playlist_nav=1) VarSet($playlist_nav_last_deck,1)
($playlist_nav=1) VarSet($playlist_nav_activity,1)
($playlist_nav=1) avPlaylistNav.Walk(+1)
}
midi.trigger[0xB0:0x54:0x00] { # Deck A Parameter knob turned clockwise
($playlist_nav=1) VarSet($playlist_nav_last_deck,0)
($playlist_nav=1) VarSet($playlist_nav_activity,1)
($playlist_nav=1) avPlaylistNav.Walk(-1)
}
midi.trigger[0xB1:0x54:0x00] { # Deck B Parameter knob turned clockwise
($playlist_nav=1) VarSet($playlist_nav_last_deck,1)
($playlist_nav=1) VarSet($playlist_nav_activity,1)
($playlist_nav=1) avPlaylistNav.Walk(-1)
}
midi.trigger[0x90:0x28:0x40] { # Deck A Parameter knob button down
($playlist_nav=1) avPlaylistNav.Load(A)
}
midi.trigger[0x91:0x28:0x40] { # Deck B Parameter knob button down
($playlist_nav=1) avPlaylistNav.Load(B)
}
av[PlaylistNav,E] {
VarSet($playlist_nav,1)
BlinkSet(~deck_a_playlist_led,1)
BlinkSet(~deck_b_playlist_led,1)
BlinkSet(~deck_a_parameter_led,3) # medium blink
BlinkSet(~deck_b_parameter_led,3)
($playlist_nav_last_deck=0) midi.HC4500.TextMsg.PlaylistNav(A,10)
($playlist_nav_last_deck=1) midi.HC4500.TextMsg.PlaylistNav(B,10)
}
av[PlaylistNav,D] {
VarSet($playlist_nav,0)
BlinkSet(~deck_a_playlist_led,0)
BlinkSet(~deck_b_playlist_led,0)
BlinkSet(~deck_a_parameter_led,0)
BlinkSet(~deck_b_parameter_led,0)
}
av[PlaylistNav.Item] {
($playlist_nav_last_deck=0) midi.HC4500.TextMsg.PlaylistNav.Item(A,30)
($playlist_nav_last_deck=1) midi.HC4500.TextMsg.PlaylistNav.Item(B,30)
}
sub[@deck_a_playlist_loadnext] { # load next item from playlist
($deck_a_playing=0) avLoadNext(A,F1) # but only if deck not playing
}
sub[@deck_b_playlist_loadnext] { # load next item from playlist
($deck_b_playing=0) avLoadNext(B,F1) # but only if deck not playing
}
########################################################
####### Auto DJ / ABM
midi.trigger[0x90:0x26:0x40] avAutoDJ(T)
av[AutoDJ,E] midi.HC4500.TextMsgSet(A,E,10,"")
av[AutoDJ,E] midi.HC4500.TextMsgSet(B,E,10,"")
av[AutoDJ,D] midi.HC4500.TextMsgSet(A,E,10,"")
av[AutoDJ,D] midi.HC4500.TextMsgSet(B,E,10,"")
midi.trigger[0x91:0x26:0x40] avABM(T)
av[ABM,E] midi.HC4500.TextMsgSet(A,E,10,"")
av[ABM,E] midi.HC4500.TextMsgSet(B,E,10,"")
av[ABM,D] midi.HC4500.TextMsgSet(A,E,10,"")
av[ABM,D] midi.HC4500.TextMsgSet(B,E,10,"")
########################################################
####### ABM Active
av[ABMActive,E] {
VarSet($abm_active,1)
midi.HC4500.TextMsgSet(A,E,20,F1,"")
midi.HC4500.TextMsgSet(B,E,20,F1,"")
}
av[ABMActive,D] {
VarSet($abm_active,0)
midi.HC4500.TextMsgSet(A,E,20,F1,"")
midi.HC4500.TextMsgSet(B,E,20,F1,"")
}
var.set[$abm_active=1] {
BlinkSet(~deck_a_func_1_led,4) # fast blink
BlinkSet(~deck_a_func_2_led,12) # inverse fast blink
BlinkSet(~deck_a_func_3_led,4)
BlinkSet(~deck_a_func_4_led,12)
BlinkSet(~deck_a_func_5_led,4)
BlinkSet(~deck_b_func_1_led,12)
BlinkSet(~deck_b_func_2_led,4)
BlinkSet(~deck_b_func_3_led,12)
BlinkSet(~deck_b_func_4_led,4)
BlinkSet(~deck_b_func_5_led,12)
}
var.set[$abm_active=0] {
($deck_a_bend_tempo=0) BlinkSet(~deck_a_func_1_led,0)
($deck_a_bend_tempo=1) BlinkSet(~deck_a_func_1_led,1)
($deck_a_zorphing=0) BlinkSet(~deck_a_func_2_led,0)
($deck_a_zorphing=1) BlinkSet(~deck_a_func_2_led,3) # medium blink
BlinkSet(~deck_a_func_3_led,0)
($deck_a_video_block=0) BlinkSet(~deck_a_func_4_led,0)
($deck_a_video_block=1) BlinkSet(~deck_a_func_4_led,3) # medium blink
($video_master=0) BlinkSet(~deck_a_func_5_led,1)
($video_master!=0) BlinkSet(~deck_a_func_5_led,0)
($deck_b_bend_tempo=0) BlinkSet(~deck_b_func_1_led,0)
($deck_b_bend_tempo=1) BlinkSet(~deck_b_func_1_led,1)
($deck_b_zorphing=0) BlinkSet(~deck_b_func_2_led,0)
($deck_b_zorphing=1) BlinkSet(~deck_b_func_2_led,3) # medium blink
BlinkSet(~deck_b_func_3_led,0)
($deck_b_video_block=0) BlinkSet(~deck_b_func_4_led,0)
($deck_b_video_block=1) BlinkSet(~deck_b_func_4_led,3) # medium blink
($video_master=1) BlinkSet(~deck_b_func_5_led,1)
($video_master!=1) BlinkSet(~deck_b_func_5_led,0)
}
av[ABMBeat.1] {
($abm_active=1) BlinkSet(~deck_a_func_1_led,1)
($abm_active=1) BlinkSet(~deck_b_func_1_led,1)
($abm_active=1) BlinkSet(~deck_a_func_5_led,1)
($abm_active=1) BlinkSet(~deck_b_func_5_led,1)
($abm_active=1) BlinkSet(~deck_a_func_4_led,0)
($abm_active=1) BlinkSet(~deck_b_func_4_led,0)
}
av[ABMBeat.2] {
($abm_active=1) BlinkSet(~deck_a_func_2_led,1)
($abm_active=1) BlinkSet(~deck_b_func_2_led,1)
($abm_active=1) BlinkSet(~deck_a_func_1_led,0)
($abm_active=1) BlinkSet(~deck_b_func_1_led,0)
($abm_active=1) BlinkSet(~deck_a_func_5_led,0)
($abm_active=1) BlinkSet(~deck_b_func_5_led,0)
}
av[ABMBeat.3] {
($abm_active=1) BlinkSet(~deck_a_func_3_led,1)
($abm_active=1) BlinkSet(~deck_b_func_3_led,1)
($abm_active=1) BlinkSet(~deck_a_func_2_led,0)
($abm_active=1) BlinkSet(~deck_b_func_2_led,0)
}
av[ABMBeat.4] {
($abm_active=1) BlinkSet(~deck_a_func_4_led,1)
($abm_active=1) BlinkSet(~deck_b_func_4_led,1)
($abm_active=1) BlinkSet(~deck_a_func_3_led,0)
($abm_active=1) BlinkSet(~deck_b_func_3_led,0)
}
########################################################
####### Initialisation message
timer.tick ($init_counter!=0) VarDec($init_counter)
var.set[$init_counter=0] {
midi.HC4500.TextMsg.OtsAV.Product(A,30)
midi.HC4500.TextMsg.OtsAV.Product(B,30)
midi.HC4500.TextMsg.OtsAV.Version(A,30,F1)
midi.HC4500.TextMsg.OtsAV.Version(B,30,F1)
}
########################################################
####### Deck A: Looping functionality
# maintain button states for flip, a1, a2 & exit
midi.trigger[0x90:0x36:0x40] VarSet($deck_a_flip,1)
midi.trigger[0x80:0x36:0x00] VarSet($deck_a_flip,0)
midi.trigger[0x90:0x37:0x40] VarSet($deck_a_a1,1)
midi.trigger[0x80:0x37:0x00] VarSet($deck_a_a1,0)
midi.trigger[0x90:0x38:0x40] VarSet($deck_a_a2,1)
midi.trigger[0x80:0x38:0x00] VarSet($deck_a_a2,0)
midi.trigger[0x90:0x40:0x40] VarSet($deck_a_exit,1)
midi.trigger[0x80:0x40:0x00] VarSet($deck_a_exit,0)
# maintain $deck_a_mod: 0 = neither buttons held,
# 1 = flip held, 2 = exit held, 3 = both held
var.set[$deck_a_flip=1] {
($deck_a_exit=0) VarSet($deck_a_mod,1)
($deck_a_exit=1) VarSet($deck_a_mod,3)
}
var.set[$deck_a_flip=0] {
($deck_a_exit=0) VarSet($deck_a_mod,0)
($deck_a_exit=1) VarSet($deck_a_mod,2)
}
var.set[$deck_a_exit=1] {
($deck_a_flip=0) VarSet($deck_a_mod,2)
($deck_a_flip=1) VarSet($deck_a_mod,3)
}
var.set[$deck_a_exit=0] {
($deck_a_flip=0) VarSet($deck_a_mod,0)
($deck_a_flip=1) VarSet($deck_a_mod,1)
}
# dispatch commands
midi.trigger[0x90:0x37:0x40] { # A1
($deck_a_mod=0) avLooping.MarkA.1(A)
($deck_a_mod=2) avLooping.EnterLoop.1(A)
}
midi.trigger[0x90:0x38:0x40] { # A2
($deck_a_mod=0) avLooping.MarkA.2(A)
($deck_a_mod=2) avLooping.EnterLoop.2(A)
}
midi.trigger[0x90:0x39:0x40] { # B
($deck_a_mod=0) avLooping.MarkB(A)
($deck_a_mod=1) avLooping.MarkB(A,F0) # suppress beat-snapping
}
midi.trigger[0x90:0x40:0x40] {
avLooping.CancelAll(A,F0) # Exit-Reloop
}
midi.trigger[0x90:0x07:0x40] { # note this button also used for avBPMMatch.Tempo() when "shift" held
($deck_a_shift=0) avTapBPM(A) # send beat trigger for BPM detection
}
########################################################
####### Deck B: Looping functionality
# maintain button states for flip, a1, a2 & exit
midi.trigger[0x91:0x36:0x40] VarSet($deck_b_flip,1)
midi.trigger[0x81:0x36:0x00] VarSet($deck_b_flip,0)
midi.trigger[0x91:0x37:0x40] VarSet($deck_b_a1,1)
midi.trigger[0x81:0x37:0x00] VarSet($deck_b_a1,0)
midi.trigger[0x91:0x38:0x40] VarSet($deck_b_a2,1)
midi.trigger[0x81:0x38:0x00] VarSet($deck_b_a2,0)
midi.trigger[0x91:0x40:0x40] VarSet($deck_b_exit,1)
midi.trigger[0x81:0x40:0x00] VarSet($deck_b_exit,0)
# maintain $deck_a_mod: 0 = neither buttons held,
# 1 = flip held, 2 = exit held, 3 = both held
var.set[$deck_b_flip=1] {
($deck_b_exit=0) VarSet($deck_b_mod,1)
($deck_b_exit=1) VarSet($deck_b_mod,3)
}
var.set[$deck_b_flip=0] {
($deck_b_exit=0) VarSet($deck_b_mod,0)
($deck_b_exit=1) VarSet($deck_b_mod,2)
}
var.set[$deck_b_exit=1] {
($deck_b_flip=0) VarSet($deck_b_mod,2)
($deck_b_flip=1) VarSet($deck_b_mod,3)
}
var.set[$deck_b_exit=0] {
($deck_b_flip=0) VarSet($deck_b_mod,0)
($deck_b_flip=1) VarSet($deck_b_mod,1)
}
# dispatch commands
midi.trigger[0x91:0x37:0x40] { # A1
($deck_b_mod=0) avLooping.MarkA.1(B)
($deck_b_mod=2) avLooping.EnterLoop.1(B)
}
midi.trigger[0x91:0x38:0x40] { # A2
($deck_b_mod=0) avLooping.MarkA.2(B)
($deck_b_mod=2) avLooping.EnterLoop.2(B)
}
midi.trigger[0x91:0x39:0x40] { # B
($deck_b_mod=0) avLooping.MarkB(B)
($deck_b_mod=1) avLooping.MarkB(B,F0) # suppress beat-snapping
}
midi.trigger[0x91:0x40:0x40] {
avLooping.CancelAll(B,F0) # Exit-Reloop
}
midi.trigger[0x91:0x07:0x40] { # note this button also used for avBPMMatch.Tempo() when "shift" held
($deck_b_shift=0) avTapBPM(B) # send beat trigger for BPM detection
}